package org.Image.management.ViewService.Game.Node;

import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.Image.management.SpringDataService.Service.StorageIo.Pojo.Mapper.FileStorage;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Slf4j
public class ImageZoomPane extends BorderPane {

    private final ImageView showImage = new ImageView();
    private final Slider HScroll = new Slider();
    private final Slider VScroll = new Slider();
    private final Slider zoomLvl = new Slider(1, 6, 1);
    private final Label hint = new Label();
    private final Label value = new Label();
    private final Label fileName = new Label();
    private final Label CreationTime = new Label();

    private double initImageX;
    private double initImageY;
    private int imageHeight;
    private int imageWidth;
    //offSetX:图片偏移的X, offSetY:图片偏移的Y ,zoomNumeric: 缩放数值
    private double offSetX, offSetY, zoomNumeric;

    @Setter
    private int initRatio = 500;

    // 构造函数
    public ImageZoomPane() {
        initializeComponents();
        setupLayout();
        setupBindings();
    }

    // 初始化组件
    public void initializeComponents() {
        imageWidth = 0;
        imageHeight = 0;

        zoomNumeric = 1;

        initImageX = 0;
        initImageY = 0;

        zoomLvl.setValue(1);
        zoomLvl.setVisible(false);

        showImage.setFitHeight(500);
        showImage.setFitWidth(500);
        showImage.setPreserveRatio(true);
        showImage.setImage(null);
        showImage.setVisible(false);

        VScroll.setMaxHeight(500);
        VScroll.setMinHeight(500);
        VScroll.setVisible(false);

        HScroll.setMaxWidth(500);
        HScroll.setMinWidth(500);
        HScroll.setVisible(false);

        fileName.setText("");
        fileName.setVisible(false);

        CreationTime.setText("");
        CreationTime.setVisible(false);

        hint.setVisible(false);
        value.setVisible(false);
    }

    // 初始化组件
    private void initializeComponents(double Width, double Height, FileStorage FileData) {

        fileName.setText("文件名称：" + FileData.getName());
        fileName.setVisible(true);
        LocalDateTime createdAt = FileData.getCreatedAt();

        // 时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        CreationTime.setText("上传时间：" + createdAt.format(formatter));
        CreationTime.setVisible(true);

        //设置右侧垂直拖动滑动条
        VScroll.setMin(0);
        VScroll.setMax(Height);

        // 配置垂直滚动条
        VScroll.setOrientation(Orientation.VERTICAL);
        // 配置水平滚动条
        HScroll.setMin(0);
        HScroll.setMax(Width);

        // 配置缩放滑块
        zoomLvl.setValue(1);
        zoomLvl.setVisible(true);

        // 配置标签
        hint.setText("缩放");
        hint.setVisible(true);

        value.setText(String.valueOf(zoomNumeric));
        value.setVisible(true);
    }

    // 设置布局
    private void setupLayout() {

        //  创建水平滚动条
        VBox topBox = new VBox(fileName,CreationTime, HScroll);
        topBox.setAlignment(Pos.TOP_CENTER);
        VBox.setVgrow(CreationTime, Priority.ALWAYS);
        VBox.setMargin(CreationTime, new Insets(2, 0, 0, 0));
        VBox.setVgrow(HScroll, Priority.ALWAYS);
        VBox.setMargin(HScroll, new Insets(2, 0, 0, 0));
        this.setTop(topBox);

        // 创建垂直滚动条
//        this.setLeft(VScroll);
        this.setRight(VScroll);

        // 创建图像
        this.setCenter(showImage);

        // 创建底部控制面板
        HBox controlBox = new HBox(hint, zoomLvl, value);
        controlBox.setAlignment(Pos.TOP_CENTER);
        controlBox.setMaxHeight(10);

        VBox.setVgrow(controlBox, Priority.ALWAYS);
        VBox.setMargin(controlBox, new Insets(30, 0, 0, 0));

        // 将组件添加到主容器
        this.setBottom(controlBox);

        this.setBorder(new Border(new BorderStroke(Color.rgb(255, 250, 250), BorderStrokeStyle.DOTTED, new CornerRadii(5), new BorderWidths(2))));
    }

    // 设置绑定
    private void setupBindings() {
        //鼠标在图片上松开的事件
        showImage.setOnMouseReleased(e -> {
            showImage.setCursor(Cursor.OPEN_HAND);
        });

        //鼠标在图片上拖动的事件
        showImage.setOnMouseDragged(e -> {
            HScroll.setValue(HScroll.getValue() + (initImageX - e.getSceneX()));
            VScroll.setValue(VScroll.getValue() - (initImageY - e.getSceneY()));
            initImageX = e.getSceneX();
            initImageY = e.getSceneY();
        });

        //鼠标在图片上滚轮滚动控制缩放的事件。缩放程度限制在1到4，每次滚动缩放0.3
        showImage.setOnScroll(event -> {
            if (event.getDeltaY() == 0) {
                return;
            }

            zoomNumeric = zoomLvl.getValue();

            if (event.getDeltaY() > 0 && zoomNumeric <= 6) {
                zoomLvl.setValue(zoomNumeric + 0.5);
                return;
            }

            if (zoomNumeric > 1) {
                zoomLvl.setValue(zoomNumeric - 0.5);
            }
        });
        //鼠标在图片上按压的事件
        showImage.setOnMousePressed(e -> {
            initImageX = e.getSceneX();
            initImageY = e.getSceneY();
            showImage.setCursor(Cursor.CLOSED_HAND);
        });
        //顶部滑动条变化时的出发事件
        HScroll.valueProperty().addListener(e -> {
            offSetX = HScroll.getValue();
            updateScrollBarsVisibility();
        });

        //右侧滑动条变化时的出发事件
        VScroll.valueProperty().addListener(e -> {
            offSetY = imageHeight - VScroll.getValue();
            updateScrollBarsVisibility();
        });

        //底部滑动条变化时的出发事件
        zoomLvl.valueProperty().addListener(e -> {
            zoomNumeric = zoomLvl.getValue();

            double newValue = (double) ((int) (zoomNumeric * 10)) / 10;
            value.setText(String.valueOf(newValue));
            if (zoomNumeric == 1) {
                VScroll.setVisible(false);
                HScroll.setVisible(false);
            } else {
                VScroll.setVisible(true);
                HScroll.setVisible(true);
            }
            if (offSetX < (imageWidth / newValue) / 2) {
                offSetX = (imageWidth / newValue) / 2;
            }
            if (offSetX > imageWidth - ((imageWidth / newValue) / 2)) {
                offSetX = imageWidth - ((imageWidth / newValue) / 2);
            }
            if (offSetY < (imageHeight / newValue) / 2) {
                offSetY = (imageHeight / newValue) / 2;
            }
            if (offSetY > imageHeight - ((imageHeight / newValue) / 2)) {
                offSetY = imageHeight - ((imageHeight / newValue) / 2);
            }

            HScroll.setValue(offSetX);
            VScroll.setValue(imageHeight - offSetY);
            showImage.setViewport(new Rectangle2D(offSetX - ((imageWidth / newValue) / 2), offSetY - ((imageHeight / newValue) / 2), imageWidth / newValue, imageHeight / newValue));
        });
    }

    // 更新滚动条的可见性
    private void updateScrollBarsVisibility() {
        zoomNumeric = zoomLvl.getValue();

        double newValue = (double) ((int) (zoomNumeric * 10)) / 10;
        value.setText(String.valueOf(newValue));
        if (offSetY < (imageHeight / newValue) / 2) {
            offSetY = (imageHeight / newValue) / 2;
        }
        if (offSetY > imageHeight - ((imageHeight / newValue) / 2)) {
            offSetY = imageHeight - ((imageHeight / newValue) / 2);
        }

        showImage.setViewport(new Rectangle2D(offSetX - ((imageWidth / newValue) / 2), offSetY - ((imageHeight / newValue) / 2), imageWidth / newValue, imageHeight / newValue));
    }

    // 公共方法
    public void setImage(Image image, FileStorage FileData) {
        if (image == null) {
            initializeComponents();
            return;
        }
        double width = image.getWidth();
        double height = image.getHeight();
//        log.info("图片长:{}宽:{}", width, height);
//        log.info("文件属性:{}", FileData);
        //获取图片长宽比
        double ratio = width / height;

        //设置长宽
        if (initRatio / ratio < initRatio) {
            imageWidth = initRatio;
            imageHeight = (int) (initRatio / ratio);
        } else if (initRatio * ratio < initRatio) {
            imageHeight = initRatio;
            imageWidth = (int) (initRatio * ratio);
        } else {
            imageHeight = initRatio;
            imageWidth = initRatio;
        }

        // 配置图像视图
        showImage.setImage(image);
        showImage.setFitWidth(imageWidth);
        showImage.setFitHeight(imageHeight);
        VScroll.setMaxHeight(imageHeight);
        VScroll.setMinHeight(imageHeight);
        HScroll.setMaxWidth(imageWidth);
        HScroll.setMinWidth(imageWidth);

        showImage.setPreserveRatio(false);
        showImage.setVisible(true);
        //设置图片缩放
        showImage.setViewport(new Rectangle2D(0, 0, width, height));

        offSetX = width / 2;
        offSetY = height / 2;
        imageHeight = (int) height;
        imageWidth = (int) width;
        initializeComponents(width, height, FileData);
    }

}
